﻿@using Resource;
@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" />
    <meta http-equiv="Expires" content="0">
    <meta http-equiv="Pragma" content="no-cache">
    <meta http-equiv="Cache-control" content="no-cache">
    <meta http-equiv="Cache" content="no-cache">
    @{
        await Html.RenderPartialAsync("/Views/Shared/_LayoutScript.cshtml");
    }
    @{
        await Html.RenderPartialAsync("/Views/Shared/_StyleCss.cshtml");
    }
    <script src="/lib/xlsx/xlsx.full.min.js?v=@DateTime.Now.Ticks"></script>
    <link href="/css/OutputPlanReport.css?v=@DateTime.Now.Ticks" rel="stylesheet" />
    <title>OutputPlanReport</title>
    <style type="text/css">
        /*报表样式*/
        html, body {
            background: url(../images/ProcessCapacity/bgwhite.png) no-repeat;
            background-size: cover;
            font-size: .16rem;
            color: #ffffff;
            position: relative;
            width: 100%;
            height: 100%;
            font-family: myFirstFont !important;
            color: black;
        }
     
        .rightTop {
            background-color: #f7fdff;
        }

        .dropbtn, button {
            background-color: #0aa9cd;
        }

        #query > button {
            background-color: #0aa9cd;
            border: 2px solid #0aa9cd;
        }

        .dropdown-content {
            background-color: #12bed0;
        }

        .Zebra {
            background-color: #e5ecff;
        }

        .ZebraNo {
            background-color: #e8f1f9;
        }

        .ZebraTo {
            background-color: #ffffff;
        }

        .warn {
            background-color: #ffcccc;
        }

        .note {
            color: red;
            font-size: 0.15rem;
            font-weight: bolder;
        }

        .warning {
            background-color: #ffaf0078;
            border-color: transparent;
        }

        .danger {
            background-color: #ff1f0078;
            border-color: transparent;
        }

        .jobnum:hover {
            background-color: #b3f1fe;
        }

        .truncate {
            /* max-width: 1.2rem; */
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            border-color: transparent;
        }

        td.percentage {
            border-color: transparent;
        }
        /*END*/

        #Tab1 {
            /* border: 1px solid #59ebe8; */
            height: 9.6rem;
            background-image: url('../images/loading.gif');
            background-size: 0.8rem 0.8rem;
            background-repeat: no-repeat;
            background-position: center;
        }

        #yield_tbody {
            border-collapse: collapse;
        }

        #yield_tbody tr,
        #yield_tbody td {
            /* border: 1px solid gray; */
        }

        .switch-container {
            display: flex;
            align-items: center;
        }

        #plan-report {
            max-height: 8.2rem;
        }
        .switch {
            position: relative;
            display: inline-block;
            width: 0.42rem;
            height: 0.24rem;
            top: 0.1rem;
        }

        .switch input {
            opacity: 0;
            width: 0;
            height: 0;
        }

        .slider {
            position: absolute;
            cursor: pointer;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: #ccc;
            transition: 0.4s;
            border-radius: 0.5rem;
        }

        .slider:before {
            position: absolute;
            content: "";
            height: 0.18rem;
            width: 0.18rem;
            left: 0.03rem;
            bottom: 0.028rem;
            background-color: white;
            transition: 0.4s;
            border-radius: 50%;
        }

        input:checked + .slider {
            background-color: #4caf50;
        }

        input:checked + .slider:before {
            transform: translateX(0.18rem);
        }

        #myTable thead th {
            position: sticky;
            top: 0;
            background-color: #a2c2e2;
            z-index: 5;
        }

        /* 固定前四列 */
        #myTable th:nth-child(-n+4) {
            position: sticky;
            z-index: 4;
            /* background-color: #a2c2e2; */
        }

        #myTable td:nth-child(-n+4) {
            position: sticky;
            z-index: 4;
            background-color: inherit;
        }

        /* 逐列调整 left 值，确保不被覆盖 */
        #myTable th:first-child,
        #myTable td:first-child {
            left: 0px;
        }

        #myTable th:nth-child(2),
        #myTable td:nth-child(2) {
            left: 0.85rem;
        }

        #myTable th:nth-child(3),
        #myTable td:nth-child(3) {
            left: 1.5rem;
        }

        #myTable th:nth-child(4),
        #myTable td:nth-child(4) {
            left: 2.2rem;
        }

        /*
        #myTable th:nth-child(5),
        #myTable td:nth-child(5) {
            left: 3.4rem;
        }
        */

        /* 确保表头的前四列有最高层级 */
        #myTable th:nth-child(-n+4) {
            z-index: 6;
        }

        #footer_tbody td:nth-child(2){
            left: 3.48rem;
        }

        #footer_tbody td:nth-child(-n+1) {
            z-index: 6;
        }

        #footer_tbody {
            font-size: 0.13rem;
            position: sticky;
            bottom: 0;
            background-color:white;
        }

        #footer_tbody tr td {
            border: 1px solid #c2c3c4;
        }

        tbody:hover .zebracro {
            background-color: #164362;
        }

        .accordion-header {
            border-radius: 8px;
            background: #eee;
            padding: 0.12rem;
            cursor: pointer;
            border-bottom: 1px solid #ddd;
            font-weight: bold;
            font-size:0.15rem;
            display: flex;
            align-items: center;
            transition: background 0.3s;
        }

        .accordion-header:hover {
            background: #eee;
        }

        .accordion-header .arrow {
            width: 0;
            height: 0;
            margin-right: 0.15rem;
            border-top: 5px solid transparent;
            border-bottom: 5px solid transparent;
            border-left: 8px solid #0aa9cd;
            transition: transform 0.3s;
        }

        .accordion-header.active .arrow {
            transform: rotate(90deg);
        }

        .accordion-content {
            display: none;
            padding: 0.03rem;
            background: #fff;
        }

        td[contenteditable="true"] {
            outline: none;
        }

        td[contenteditable="true"]:focus {
            outline: 2px solid #0060df;
        }
    </style>
</head>
<body class="fill-parent" style="overflow-y: hidden; color: black;">
    <div class="main">
        <div class="header">
            <div class="header-left fl">
                <img src="/images/logo.png?v=@DateTime.Now.Ticks" class="scaled-image" draggable="false" oncontextmenu="return false;" ondragstart="return false;" />
            </div>
            <div class="btn">
                <spn>
                    <div id="query">
                        <div class="dropdown">
                            <button class="dropbtn">@Label.Desktop</button>
                            <div class="dropdown-content">
                                <a class="menudropdown" href=@Html.Raw($"https://dashboard.li.lumentuminc.net/API/DesktopApp/Dashboard.exe?v={DateTime.Now.Ticks}") download>@Label.Local</a>
                                <a class="menudropdown" href=@Html.Raw($"https://dashboard.li.lumentuminc.net/API/DesktopApp/Dashboard_lnk.zip?v={DateTime.Now.Ticks}") download>@Label.Shortcut</a>
                            </div>
                        </div>
                        <div class="dropdown">
                            <button class="dropbtn">@Label.Data@Label.Datum</button>
                            <div class="dropdown-content">
                                <a class="menudropdown" onclick="exportDdata('OutputPlan')">@Label.Data@Label.Export</a>
                            </div>
                        </div>
                        <div class="dropdown">
                            <button class="dropbtn">@Label.Language</button>
                            <div class="dropdown-content">
                                <a class="menudropdown" onclick="setLanguageCookie('@Const.CNLANGUAGE')">@Label.Chinese</a>
                                <a class="menudropdown" onclick="setLanguageCookie('@Const.USLANGUAGE')">@Label.English</a>
                            </div>
                        </div>
                        <button class="modalBtn dimension">@Label.Full</button>
                    </div>
                </spn>
            </div>
            <div class="header-center fl">
                <div class="header-title"></div>
                <div class="header-img"></div>
            </div>
            <div class="header-right fl" id="time"></div>
            <div class="header-bottom fl"></div>
        </div>
        <div class="center">
            <div class="center-left fl">
                <div class="left-top rightTop border">
                    <div class="title note">@Label.Note_OutputPlanReport</div>
                    <div id="board" class="chart">
                        <div class="query">
                            <span id="dateto">
                                <span class="titleinput tle">@Label.Time:</span>
                                <select id="startyear" placeholder="select date"></select>
                                <select id="startto"></select>
                                <span class="titleinput tle">@Label.To</span>
                                <select id="endyear" placeholder="select date"></select>
                                <select id="endto" style="margin-right: 0.1rem;"></select>
                            </span>
                            <span class="titleinput tle">PN:</span>
                            <select id="cmb_part_number" placeholder="select PartNumber" style="width: 1.8rem;"></select>
                            <span class="titleinput tle">Project:</span>
                            <select id="cmb_project" placeholder="select Project" >
                                <option value="ALL">ALL</option>
                            </select>
                            <button id="btn_query" class="btn btn-primary  btn-sm col-md-12" type="button" onclick="Getdata()">@Label.Query</button>
                        </div>
                        <div id="Tab1">
                            <div id="chart-container">
                                <div class="accordion">
                                    <div class="accordion-item" id="report-item">
                                        <div class="accordion-header"><span class="arrow"></span> Report</div>
                                        <div class="accordion-content">
                                            <div id="plan-report"></div>
                                            <div class="addreason" style="padding:0.05rem;">
                                                <button onclick="addFooterRow()">➕备注行</button>
                                                <button class="action-btn" onclick="saveReasons()">💾保存</button>
                                                <button class="action-btn" onclick="deltReasons()">❌删除</button>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="accordion-item" id="chart-item">
                                        <div class="accordion-header"><span class="arrow"></span>Output Plan Chart</div>
                                        <div class="accordion-content">
                                            <div class="tab tab-chart"></div>
                                            <div id="plan-chart"></div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <script src="/js/accordion.js"></script>
    <script type="text/javascript" href="?v=@DateTime.Now.Ticks">
        $(function () {
            $('.accordion').simpleAccordion({
                activeIndex: 'all',  // 展开全部项
                multi: true,         // 多项同时展开
                speed: 400           // 动画时间为 400ms
            });
        });

        $(document).ready(function () {
            var whei = $(window).height();
            $("html").css({ fontSize: whei / 12.5 });
            $(window).resize(function () {
                if ($(".dimension").text() == "@Html.Raw(Label.Full)") {
                    var whei = $(window).height();
                    $("html").css({ fontSize: whei / 12.5 });
                }
                else {
                    var whei = $(window).width();
                    $("html").css({ fontSize: whei / 22 })
                }
            });

            function numberToUpperCase(number) {
                var uppercaseMonths = [
                    '一月', '二月', '三月', '四月', '五月', '六月',
                    '七月', '八月', '九月', '十月', '十一月', '十二月'
                ];
                return uppercaseMonths[number - 1];
            }
            var myDate = new Date();
            var result = numberToUpperCase(myDate.getMonth() + 1);
            $('.header-title').html("@Html.Raw(Label.Board_OutputPlanReport)");
            function getTime() {
                var myDate = new Date();
                var myYear = myDate.getFullYear();
                var myMonth = myDate.getMonth() + 1;
                var myToday = myDate.getDate();
                var myDay = myDate.getDay();
                var myHour = myDate.getHours();
                var myMinute = myDate.getMinutes();
                var mySecond = myDate.getSeconds();
                var week = ['@Label.Sunday', '@Label.Monday', '@Label.Tuesday', '@Label.Wednesday', '@Label.Thursday', '@Label.Friday', '@Label.Saturday'];
                var nowTime;

                nowTime = myYear + '-' + fillZero(myMonth) + '-' + fillZero(myToday) + '&nbsp;&nbsp;' + fillZero(myHour) + ':' + fillZero(myMinute) + ':' + fillZero(mySecond) + '&nbsp;&nbsp;' + week[myDay] + '&nbsp;&nbsp;';
                $('#time').html(nowTime);
            };
            function fillZero(str) {
                var realNum;
                if (str < 10) {
                    realNum = '0' + str;
                } else {
                    realNum = str;
                }
                return realNum;
            }
            setInterval(getTime, 1000);
            // 设置全屏
            $('.dimension').on('click', function (e) {
                var element = document.documentElement;
                if ($(".dimension").text() == "@Html.Raw(Label.Full)") {
                    // 判断浏览器设备类型
                    if (element.requestFullscreen) {
                        element.requestFullscreen();
                    } else if (element.mozRequestFullScreen) {       //兼容火狐
                        element.mozRequestFullScreen();
                    } else if (element.webkitRequestFullscreen) {    //兼容谷歌
                        element.webkitRequestFullscreen();
                    } else if (element.msRequestFullscreen) {        //兼容IE
                        element.msRequestFullscreen();
                    }
                    $(".dimension").text("@Html.Raw(Label.Exit + Label.Full)");
                } else {
                    if (document.exitFullscreen) {
                        document.exitFullscreen();
                    } else if (document.mozCancelFullScreen) {
                        document.mozCancelFullScreen();
                    } else if (document.webkitCancelFullScreen) {
                        document.webkitCancelFullScreen();
                    } else if (document.msExitFullscreen) {
                        document.msExitFullscreen();
                    }
                    $(".dimension").text("@Html.Raw(Label.Full)");
                }
            });
            $('#btn_query').prop('disabled', true);
        });

        //下拉框设置
        var startdate, enddate;
        var Datesetting = function() {
            $("#startdate, #enddate, #startyear, #startto, #endyear, #endto").css({
                "height": "0.36rem",
                "transform": "translateY(0.02rem)"
            });
            function addOptions(selectId, options) {
                var $select = $(selectId);
                $select.empty();
                options.forEach(function(option) {
                    $select.append(new Option(option.label, option.value));
                });
            }
            //设置年
            var currentYear = new Date().getFullYear();
            var previousYear = currentYear - 1;
            addOptions('#startyear, #endyear', [{ label: previousYear, value: previousYear },{ label: currentYear, value: currentYear }]);
            //设置月
            var options = [];
            for (var month = 1; month <= 12; month++) {
                options.push({ label: "Month" + String(month).padStart(2, "0"), value: String(month).padStart(2, "0") });
            }
            addOptions('#startto, #endto', options);
            //默认年
            var prevMonth = new Date(currentYear, new Date().getMonth() - 1, 1);
            $('#startyear').val(prevMonth.getFullYear());
            $('#endyear').val(currentYear);
            //默认月
            var currentMonth = new Date().getMonth() + 1;
            var nextMonth = currentMonth === 12 ? 1 : currentMonth + 1;
            $('#startto').val(String(currentMonth).padStart(2, "0"));
            $('#endto').val(String(nextMonth).padStart(2, "0"));
            startdate = parseInt($("#startyear").val() + $("#startto").val());
            enddate = parseInt($("#endyear").val() + $("#endto").val());
        }

        function tabchart(){
           $('.tab').empty();
           var startdate = parseInt($("#startyear").val() + $("#startto").val());
           var enddate = parseInt($("#endyear").val() + $("#endto").val());
           let htmltext = '<div class="tab tab-chart">\n';
            for (let date = startdate; date <= enddate; date++) {
                let year = Math.floor(date / 100);
                let month = date % 100;
                let displayMonth = month.toString().padStart(2, '0');
                let isActive = (date === startdate) ? 'active' : '';
                htmltext += `<button class="tablinks ${isActive}" onclick="OpenTab(event,'tab-chart','plan-chart',OutputPlanTab,'${date}')">${displayMonth}&nbsp;Month&nbsp;Output&nbsp;Chart</button>\n`;
            }
            htmltext += '</div>';
            $('.tab-chart').append(htmltext);
        }

        //ComBoxYield
        var ComboxAction = function () {
            Datesetting();
            var header_key = {
                start: parseInt($("#startyear").val() + $("#startto").val()),
                end: parseInt($("#endyear").val() + $("#endto").val())
            };
            var pam = {};
            pam.header_key = JSON.stringify(header_key);
            getoutputplan(pam);
        };

        function getoutputplan(pam) {
            $.post(api + "/ReportAction/GetOutputPlanProject", pam, function(response) {
                const partnumber = response.ReturnData.partnumber;
                const project = response.ReturnData.project;
                $('#cmb_part_number').empty();
                partnumber.forEach(item => {
                    $('#cmb_part_number').append(new Option(item.text, item.value));
                });

                $('#cmb_part_number').on('change', function() {
                    const selectedPartnumber = $(this).val();
                    const filteredProject = selectedPartnumber ? project.filter(item => item.partnumber === selectedPartnumber) : [{ text: "ALL", value: "ALL" }];
                    $('#cmb_project').empty().append(new Option("ALL", "ALL"));
                    filteredProject.forEach(item => {
                        $('#cmb_project').append(new Option(item.text, item.value));
                    });
                });
                if (partnumber.length > 0) {
                    $('#cmb_part_number').val(partnumber[0].value).trigger('change');
                }
                getdate();
            }, "json");
        }

        $("#startto,#endto").on("change", function () {
            var header_key = {
                start: parseInt($("#startyear").val() + $("#startto").val()),
                end: parseInt($("#endyear").val() + $("#endto").val())
            };
            var pam = {};
            pam.header_key = JSON.stringify(header_key);
            getoutputplan(pam);
        });

        //图表自适应大小
        const chartsMap = new Map();
        const chartIds = ['plan-report', 'plan-chart'];
        function echartsautomatic(xAxisDataMap) {
            window.addEventListener("resize", () => {
                chartsMap.forEach((chart, chartId) => {
                    chart.resize();
                    if (chartId === 'plan-chart') {
                        const { chart, xAxisData, planData, actualData, varData } = xAxisDataMap.get(chartId);
                        updateFpyGraphics(chart, xAxisData, planData, actualData, varData);
                    }
                });
            });
        }

        //定时查询
        var Tabtimer;
        function TabInterval() {
            clearInterval(Tabtimer);
            //每隔10m执行一次
            Tabtimer = setInterval(function () {
                var endDate = new Date($("#enddate").val());
                if (endDate > new Date()) {
                    getdate();
                }
            }, 10 * 60 * 1000);
        }

        $(function () {
            var startDate = new Date();
            startDate.setMonth(startDate.getMonth() - 1);
            startDate.setHours(0, 0, 0, 0);
            var endDate = new Date();
            endDate.setHours(0, 0, 0, 0);
            $('#startdate').val(startDate.toISOString().split('T')[0]);
            $('#enddate').val(endDate.toISOString().split('T')[0]);
            ComboxAction();
            // setTimeout(function () {
            //     Getdata();
            // }, 2000);
        })

        var Getdata = function () {
            getdate();
            TabInterval();
        }

        //报表导出
        var exportDdata = function(type){
            const book = XLSX.utils.book_new();
            const sheet = XLSX.utils.json_to_sheet(Tab.report);
            XLSX.utils.book_append_sheet(book, sheet);
            XLSX.writeFile(book,`${type}.xlsx`);
        }

        function loadingshow() {
            $('#btn_query').prop('disabled', true);
            $('#Tab1').css('background-image', 'url("../images/loading.gif")');
            $('#Tab1').css('background-size', '0.8rem 0.8rem');
            $('#Tab1').css('background-repeat', 'no-repeat');
            $('#Tab1').css('background-position', 'center');
        }
        function loadingnone() {
            $('#btn_query').prop('disabled', false);
            $('#Tab1').css('background-image', 'none');
        }

        function chartHeight() {
            const containerHeight = $('#chart-container').height();
            const reportHeight = $('#report-item').height();
            const chartHeight = containerHeight - reportHeight - 50;
            $('#plan-chart').height(chartHeight);
        }
        
        function resetChart(id) {
            const el = document.getElementById(id);
            echarts.getInstanceByDom(el)?.dispose();
            $(el).empty();
        }

        function resizeChartById(id) {
            const el = document.getElementById(id);
            if (!el) return;
            const chart = echarts.getInstanceByDom(el);
            if (chart) chart.resize();
        }

        function loadingChart() {
           setTimeout(() => {
                chartHeight();
                resizeChartById('plan-chart');
            }, 350);
        }

        $('.accordion-header').on('click', function () {
            loadingChart();
        });

        //获取数据
        var Tab;
        var getdate = function () {
            var startdate = parseInt($("#startyear").val() + $("#startto").val());
            var enddate = parseInt($("#endyear").val() + $("#endto").val());
            if (startdate <= enddate) {
                var header_key = {
                    start: startdate,
                    end: enddate,
                    partnumber: $('#cmb_part_number').val()
                };
                var pam = {};
                pam.proj_code = $('#cmb_project').val();
                pam.header_key = JSON.stringify(header_key);
                loadingshow();
                $.ajax({
                    type: "POST",
                    url: api + "/ReportAction/GetOutputPlanReport",
                    data: pam,
                    dataType: "json",
                    async: true,
                    success: function (result) {
                        loadingnone();
                        tabchart();
                        if (result.Success)
                        {
                            Tab = result.ReturnData;
                            ReportDetail();
                            OutputPlanTab(startdate);
                            chartHeight();
                            resizeChartById('plan-chart');
                        }
                        else{
                            $("#plan-report").empty();
                            resetChart('plan-chart');
                            alert("未查询到该时段数据！")
                        }
                    }
                });
            }
            else{
                alert("时间范围有误！");
                return;
            }
        }

        //Report
        var ReportDetail = function () {
            var data = Tab.report;
            if(data.length>0){
                $("#plan-report").empty();
                var left_table_html = `
                <table id="myTable" class="DataSheet" border="1" style="width: 100%; height: 100%;">
                    <thead><tr></tr></thead>
                    <tbody id="yield_tbody"></tbody>
                    <tfoot id="footer_tbody"><tr></tr></tfoot>
                </table>`;
                $("#plan-report").append(left_table_html);
                var table = $('#myTable');
                var tbody = table.find('tbody');
                var headerRow = table.find('thead tr');
                var headers = Object.keys(data[0]);
                headers.forEach(function (header) {
                    headerRow.append('<th>' + header + '</th>');
                });
                data.forEach(function (row, index) {
                    index++;
                    let newRow = $(`<tr class="${(index % 2) ? "ZebraNo" : "ZebraTo"}"></tr>`);
                    headers.forEach(function (header, columnindex) {
                        const value = row[header];
                        const isNegativeNumber = typeof value === 'number' && value < 0;
                        const tdClass = isNegativeNumber ? 'truncate note' : 'truncate';
                        newRow.append(`<td class="${tdClass}">${value}</td>`);
                    });
                    tbody.append(newRow);
                });
                if (Object.keys(data[0]).length > 35) {
                    $("#plan-report").css("overflow-y", "auto");
                }
                footerRemark();
            }
        }

        function footerRemark() {
            const remarkData = Tab.remark || [];
            const footer = $('#footer_tbody');
            footer.empty();
            remarkData.forEach(function (row) {
                const rowId = row.REMARK_ID;
                const remarkText = row.REMARK;
                let tr = $('<tr style="height: 0.45rem;"></tr>');
                let metaCell = $(`
                    <td colspan="4" style="padding: 4px; background-color: white;">
                        <input type="checkbox" id="${rowId}" data-tag="${rowId}">
                        <input type="text" placeholder="备注..." value="${remarkText}"style="width: 90%; font-size: 0.18rem; padding: 2px;border: 1px solid #ccc; border-radius: 4px; margin-left: 2%;">
                    </td>
                `);
                tr.append(metaCell);
                //渲染每个日期列
                Object.keys(row).forEach(function (key) {
                    if (['REMARK_ID', 'PN', 'PROJECT', 'REMARK'].includes(key)) return;
                    const raw = row[key];
                    let val = '', bg = '';
                    if (typeof raw === 'string' && raw.includes('*')) {
                        [val, bg] = raw.split('*');
                    } else {
                        val = raw;
                        bg = '';
                    }
                    //值为 "0" 或空则显示 &nbsp;
                    const showVal = (!val || val === '0') ? '&nbsp;' : val;
                    const td = $(`<td contenteditable="true" style="min-height: 30px; padding: 5px; background-color: ${bg};" title="双击更换背景颜色/右键恢复默认颜色">${showVal}</td>`);
                    //绑定调色板双击事件
                    const defaultHex = "#17e83a";
                    const defaultRgb = "rgb(23, 232, 58)";
                    td.on('dblclick', function () {
                        const colorInput = $('<input type="color" style="display: none;">');
                        colorInput.on('input', function (e) {
                            td.css('background-color', e.target.value);
                        });
                        $('body').append(colorInput);
                        colorInput.trigger('click');
                        colorInput.on('change', () => colorInput.remove());
                    });
                    //右键恢复默认颜色
                    td.on('contextmenu', function (e) {
                        e.preventDefault();
                        td.css('background-color', defaultRgb);
                    });
                    tr.append(td);
                });
                footer.append(tr);
            });
            if (remarkData.length > 0) {
                $('#footer_tbody tr').css('height', '0.45rem');
            }
        }

        //添加原因行
        function addFooterRow() {
            const tfoot = document.getElementById("footer_tbody");
            const table = document.getElementById("myTable");
            if (!table) return;

            const colCount = $(table).data("columnCount") || table.querySelectorAll("thead th").length;
            if (colCount < 5) return;

            const newRow = document.createElement("tr");
            newRow.style.height = "0.45rem";

            const mergedTd = document.createElement("td");
            mergedTd.colSpan = 4;
            mergedTd.style.padding = "4px";
            mergedTd.style.backgroundColor = "white";
            
            //const uniqueId = crypto.randomUUID().replace(/-/g, '').slice(0, 20);
            const uniqueId = Date.now();
            const checkbox = document.createElement("input");
            checkbox.type = "checkbox";
            checkbox.id = "cb-" + uniqueId;
            checkbox.setAttribute("data-tag", "cb-" + uniqueId);
            mergedTd.appendChild(checkbox);

            //添加文本框 input
            const inputBox = document.createElement("input");
            inputBox.type = "text";
            inputBox.placeholder = "备注...";
            inputBox.style.width = "90%";
            inputBox.style.fontSize = "0.18rem";
            inputBox.style.padding = "2px";
            inputBox.style.border = "1px solid #ccc";
            inputBox.style.borderRadius = "4px";
            inputBox.style.marginLeft = "2%";
            mergedTd.appendChild(inputBox);
            newRow.appendChild(mergedTd);

            const remainCols = colCount - 4;
            for (let i = 0; i < remainCols; i++) {
                const td = document.createElement("td");
                td.contentEditable = true;
                td.innerHTML = "&nbsp;";
                td.style.minHeight = "30px";
                td.style.padding = "5px";
                td.title = "双击更换背景颜色/右键恢复默认颜色";
                //默认颜色
                const defaultHex = "#17e83a";
                const defaultRgb = "rgb(23, 232, 58)";
                //添加双击事件
                td.ondblclick = () => {
                    const colorInput = document.createElement("input");
                    colorInput.type = "color";
                    colorInput.style.display = "none";
                    //设置背景
                    colorInput.oninput = (e) => {
                        td.style.backgroundColor = e.target.value;
                    };
                    //插入到 DOM 中并触发
                    document.body.appendChild(colorInput);
                    colorInput.click();
                    //选择完或取消后移除
                    colorInput.addEventListener("change", () => {
                        colorInput.remove();
                    }, { once: true });
                };
                //右键恢复默认颜色
                td.addEventListener("contextmenu", (e) => {
                    e.preventDefault(); 
                    td.style.backgroundColor = defaultRgb;
                });
                newRow.appendChild(td);
            }
            const rowCount = tfoot.querySelectorAll("tr").length;
            const chartItem = $("#chart-item");
            const content = chartItem.find(".accordion-content");
            if (rowCount > 12 && content.css("display") !== "none") {
                content.hide();
                chartItem.find(".accordion-header").removeClass("active");
            }
            tfoot.insertBefore(newRow, tfoot.firstChild);
            loadingChart();
        }

        //JSON
        function getRemarksJson() 
        {
            const table = document.getElementById("myTable");
            const tfoot = table.querySelector("tfoot");
            const rows = tfoot.querySelectorAll("tr");
            const result = {
                PN: "",
                PROJECT: "",
                LUM_YEAR: "",
                DATA: []
            };

          //从 tbody 第一个数据行提取固定信息
          const firstDataRow = document.querySelector("#yield_tbody tr");
          if (firstDataRow) {
              const infoTds = firstDataRow.querySelectorAll("td");
              result.PN = infoTds[0]?.innerText.trim() || "";
              result.PROJECT = infoTds[1]?.innerText.trim() || "";
              result.LUM_YEAR = infoTds[2]?.innerText.trim() || "";
          }

          //获取表头的日期字段，从第6列（index 5）开始
          const headerThs = table.querySelectorAll("thead tr th");
          const dateHeaders = Array.from(headerThs).slice(4).map(th => th.textContent.trim());

          //映射完整日期
          const currentYear = result.LUM_YEAR || $("#startyear").val();
          rows.forEach((row) => {
              const tds = row.querySelectorAll("td");
              if (tds.length < 5) return;
              const checkbox = row.querySelector('input[type="checkbox"]');
              const inputBox = row.querySelector('input[type="text"]');
              const remarkText = inputBox?.value.trim();
              if (!remarkText || !checkbox || !checkbox.id) return;
              const remarkId = checkbox.id; 
              //遍历每列数据与日期字段对齐）
              for (let i = 1; i < tds.length; i++) {
                  const td = tds[i];
                  const value = td.innerText.trim().replace(/\u00A0/g, ''); //去除 &nbsp;
                  if (!value) continue;
                  const background = value === '' || value === '0' ? 'transparent' : td.style.backgroundColor || 'transparent';
                  /*
                  const md = dateHeaders[i - 1]; 
                  const [mm, dd] = md.split("/");
                  const fullDate = `${currentYear}-${mm.padStart(2, "0")}-${dd.padStart(2, "0")}`;
                  */
                  const md = dateHeaders?.[i - 1];
                  if (typeof md !== 'string' || !md.includes("/")) continue;
                  const [mm, dd] = md.split("/");
                  const fullDate = `${currentYear}-${mm.padStart(2, "0")}-${dd.padStart(2, "0")}`;
                  result.DATA.push({
                      REMARK_ID: remarkId,
                      REMARK: remarkText,
                      DATE: fullDate,
                      VALUE: value,
                      BACKGROUND: background
                  });
                }
            });
            return result;
        }

        function deleteSelectedRowsAndCollectIds() {
            const checkboxes = document.querySelectorAll('#footer_tbody input[type="checkbox"]');
            const selectedIds = [];
            checkboxes.forEach(checkbox => {
                if (checkbox.checked) {
                    const checkboxId = checkbox.id;
                    if (checkboxId) {
                        selectedIds.push(checkboxId);
                    }
                    const row = checkbox.closest("tr");
                    if (row) {
                        row.remove();
                    }
                }
            });
            return selectedIds;
        }

        //delete
        function deltReasons(){
            var checkboxIds = deleteSelectedRowsAndCollectIds();
            loadingChart();
            var header_key = {
                checkbox_id: checkboxIds
            };
            var pam = {};
            pam.header_key = JSON.stringify(header_key);
            $.ajax({
                type: "POST",
                url: api + "/ReportAction/GetOutputPlanDeltReasons",
                data: pam,
                dataType: "json",
                async: true,
                success: function (result) {
                    if(result.Success){
                        alert(result.ReturnMessage);
                    }
                }
            });
        }
        
        //保存原因行
        function saveReasons(){
            var header_key = {
                jsondata: getRemarksJson()
            };
            var pam = {};
            pam.header_key = JSON.stringify(header_key);
            $.ajax({
                type: "POST",
                url: api + "/ReportAction/GetOutputPlanSaveReasons",
                data: pam,
                dataType: "json",
                async: true,
                success: function (result) {
                    if(result.Success){
                        alert(result.ReturnMessage);
                    }
                }
            });
        }

        function OpenTab(evt, panle, id, echar_name, date, itemindex = -1) {
            var i, tablinks;
            tablinks = document.getElementsByClassName(panle)[0].getElementsByClassName("tablinks");
            for (i = 0; i < tablinks.length; i++) {
                tablinks[i].className = tablinks[i].className.replace("active", "");
            }
            evt.currentTarget.className += " active";
            if(id=="process_yield"){
                $('#process_search').val('ALL');
                $('#cmb_data_type').val('DAY');
                var chart = echarts.init(document.getElementById("process_yield"));
                chart.dispose();
            }
            echar_name(date);
        }

        function OutputPlanTab(date) {
            var data = Tab.chardt;
            const year = Math.floor(date / 100);
            const month = date % 100;
            const monthStr = month.toString().padStart(2, '0');

            const filtered = data.filter(item =>
                item.LUM_YEAR === year && item.LUM_MONTH === month
            );
            const grouped = {};
            for (const row of filtered) {
                const key = `${row.PN}_${row.PROJECT}_${row.OUTPUT_TYPE}`;
                if (!grouped[key]) {
                    grouped[key] = {
                        PN: row.PN,
                        PROJECT: row.PROJECT,
                        LUM_YEAR: row.LUM_YEAR,
                        OUTPUT_TYPE: row.OUTPUT_TYPE
                    };
                }
                const formattedDate = row.OUTPUT_DATE.replace('-', '/');
                grouped[key][formattedDate] = row.OUTPUT_VALUE;
            }
            const structuredData = Object.values(grouped);
            OutputPlanChart(structuredData);
        }

        //更新 fpy 图的 graphic 图层
        function updateFpyGraphics(myChart, xAxisData, planData, actualData, varData) {
            const chartWidth = myChart.getWidth();
            const tableLeft = 60;
            const tableRight = 10;
            const tableWidth = chartWidth - tableLeft - tableRight;
            const baseBottom = 75;
            const rowHeight = 22;
            const rowCount = 3;
            const colCount = xAxisData.length;
            const cellWidth = tableWidth / colCount;
            const graphics = [];
            //表格横线
            for (let i = 0; i <= rowCount; i++) {
                graphics.push({
                    type: 'line',
                    bottom: baseBottom - i * rowHeight,
                    left: tableLeft,
                    shape: { x1: 0, y1: 0, x2: tableWidth, y2: 0 },
                    style: { stroke: '#ccc' }
                });
            }
            //表格竖线
            for (let i = 0; i <= colCount; i++) {
                graphics.push({
                    type: 'line',
                    bottom: baseBottom - rowCount * rowHeight,
                    left: tableLeft + i * cellWidth,
                    shape: { x1: 0, y1: 0, x2: 0, y2: rowHeight * rowCount },
                    style: { stroke: '#ccc' }
                });
            }

            //高亮框
            graphics.push({
                id: 'highlight-rect',
                type: 'rect',
                left: tableLeft,
                bottom: baseBottom - rowCount * rowHeight,
                shape: { width: cellWidth, height: rowHeight * rowCount },
                style: {
                    fill: 'rgba(255, 255, 0, 0.15)',
                    stroke: 'rgba(255, 215, 0, 0.4)'
                },
                z: -1
            });

            //图例与表格左侧对齐
            const legends = [
                { color: '#21618c', label: '@Html.Raw(Label.Plan)' },
                { color: '#1e8449', label: '@Html.Raw(Label.Actual)' },
                { color: '#e67e22', label: '@Html.Raw(Label.Gap)' }
            ];
            const legendCircleLeft = tableLeft - 46;
            const legendTextLeft = tableLeft - 32;

            for (let i = 0; i < legends.length; i++) {
                const item = legends[i];
                const cy = baseBottom - rowHeight * (i + 0.8);
                graphics.push({
                    type: 'circle',
                    left: legendCircleLeft,
                    bottom: cy,
                    shape: { r: 5 },
                    style: { fill: item.color }
                });
                graphics.push({
                    type: 'text',
                    left: legendTextLeft,
                    bottom: cy,
                    style: {
                        text: item.label,
                        font: '10px sans-serif',
                        fill: '#333',
                        textBaseline: 'middle'
                    }
                });
            }
            myChart.setOption({ graphic: graphics });
        }

        function OutputPlanChart(jsonData){
            const allKeys = new Set();
            jsonData.forEach(item => {
                Object.keys(item).forEach(key => {
                    if (/^\d{2}\/\d{2}$/.test(key)) allKeys.add(key);
                });
            });

            const xAxisData = Array.from(allKeys).sort((a, b) => {
                const [am, ad] = a.split('/').map(Number);
                const [bm, bd] = b.split('/').map(Number);
                return am !== bm ? am - bm : ad - bd;
            });

            function extractSeries(type) {
                const found = jsonData.find(item => item.OUTPUT_TYPE === type);
                return xAxisData.map(date => found?.[date] ?? 0);
            }

            const planData = extractSeries('Accu. Output plan Qty');
            const actualData = extractSeries('Accu. Actual output Qty');
            const varData = extractSeries('Accu. Output Var Qty');

            const chartDom = document.getElementById('plan-chart');
            if (chartDom) echarts.dispose(chartDom);
            const myChart = echarts.init(chartDom);

            const option = {
                title: {
                    text: 'Output Plan Chart',
                    left: 'left',
                    top: '1.5%',
                    textStyle: { fontSize: '0.2rem', fontWeight: 'bold' }
                },
                tooltip: {
                    trigger: 'axis',
                    textStyle: {
                        fontSize: 12,
                        color: 'bold'
                    }
                },
                toolbox: {
                    feature: {
                        saveAsImage: {
                            show: true,
                            name: `OutputPlanChart`
                        }
                    }
                },
                legend: {
                    top: '5%',
                    data: ['Accu.Output plan Qty', 'Accu.Actual Output Qty', 'Accu.Output Var Qty']
                },
                grid: { left: 60, right: 10, bottom: 100 },
                xAxis: [{
                    type: 'category',
                    data: xAxisData,
                    axisLabel: {
                        margin: 0,
                        interval: 0,
                        formatter: function (value, index) {
                            const varValue = varData[index];
                            const varText = varValue < 0 ? `{neg|${varValue}}` : `{table|${varValue}}`;
                            return (
                                `{table|${value}}\n` +
                                `{table|${planData[index]}}\n` +
                                `{table|${actualData[index]}}\n` +
                                varText
                            );
                        },
                        rich: {
                            table: {
                                align: 'center',
                                verticalAlign: 'middle',
                                fontSize: 10,
                                lineHeight: 22
                            },
                            neg: {
                                align: 'center',
                                verticalAlign: 'middle',
                                fontSize: 10,
                                lineHeight: 22,
                                color: '#e74c3c'
                            }
                        }
                    }
                }],
                yAxis: {
                    type: 'value',
                    name: 'Qty'
                },
                series: [
                    {
                        name: 'Accu.Output plan Qty',
                        data: planData,
                        type: 'line',
                        symbol: 'none',
                        lineStyle: { color: '#21618c', width: 3 }
                    },
                    {
                        name: 'Accu.Actual Output Qty',
                        data: actualData,
                        type: 'bar',
                        itemStyle: { color: '#1e8449' },
                        barGap: '10%'
                    },
                    {
                        name: 'Accu.Output Var Qty',
                        data: varData,
                        type: 'bar',
                        itemStyle: { color: '#e67e22' }
                    }
                ],
                axisPointer: {
                    link: { xAxisIndex: 'all' },
                    label: { show: false },
                    triggerTooltip: false
                }
            };

            myChart.setOption(option);
            window.addEventListener('resize', function () {
                myChart.resize();
            });

            updateFpyGraphics(myChart, xAxisData, planData, actualData, varData);
            chartsMap.set('plan-chart', myChart);

            //记录数据，供 resize 用
            if (!window.xAxisDataMap) window.xAxisDataMap = new Map();
            window.xAxisDataMap.set('plan-chart', { chart: myChart, xAxisData, planData, actualData, varData });
            echartsautomatic(window.xAxisDataMap);
            //监听交互
            myChart.on('updateAxisPointer', function (event) {
                const index = event.axesInfo?.[0]?.value;
                if (index == null || index < 0 || index >= xAxisData.length) return;
                const cellWidth = myChart.getWidth() - 60 - 10;
                const colWidth = cellWidth / xAxisData.length;
                myChart.setOption({
                    graphic: {
                        id: 'highlight-rect',
                        left: 60 + (index * colWidth)
                    }
                });
            });
        }

    </script>
</body>
</html>